﻿package{
	import flash.display.*;
	import flash.events.*
	import flash.utils.*
	import flash.text.*
	import flash.system.*
	import flash.net.*
	import flash.ui.*
	import fl.controls.*;

	import MyLoader;
	import SimpleLoader;
	import GameScene;
	import helper;
	import erlang;
	import UserInterFace;
	import animation;
	import MyGeom
	import com.adobe.serialization.json.JSON;

	public class mmorpg extends Sprite{
		var ldr:MyLoader;
		var gameScene:GameScene;
		var socket:Socket,protocol:Function;
		var dialog:TextArea
		var t0,count = 1;
		var my,info;
		var buffer:ByteArray = new ByteArray();
		var msgList:Array = [];
		var myInterface
		var clock
		var flushRate:int = 5,flushCount:int = 5;
		var lock;
		var confer:Dictionary = new Dictionary();
		const TIMEOUT = 590000
		function mmorpg(){
			gameScene = new GameScene(740,520);
			gameScene.roadPass = roadPass;
			addChild(gameScene);
			dialog = new TextArea();
			dialog.editable = false;
			dialog.setSize(220, 570);
			dialog.move(740, 0);
			dialog.focusRect = false;
			var font = new TextFormat();
			font.size = 16;
			dialog.setStyle('textFormat',font);
			addChild(dialog);
			socket = new Socket();
			ldr = new MyLoader();
			ldr.load('init','data/init.txt');
			ldr.callback = initializtion;
			//网络连接
			protocol = protocol_start;
			socket.addEventListener(ProgressEvent.SOCKET_DATA,recieve);
			connectBtn.addEventListener(MouseEvent.CLICK,function(e){
				socket.connect(info.ip,2345);
				dialog.appendText('正在连接\n');
			});
			socket.addEventListener(Event.CLOSE,function(e){
				dialog.appendText('连接断开\n');
				protocol = protocol_start;
				clearTimeout(clock);
			});
			socket.addEventListener(Event.CONNECT,function(e){
				dialog.appendText('已连接\n');
				input.addEventListener(KeyboardEvent.KEY_DOWN,keySend);
				sendBtn.addEventListener(MouseEvent.CLICK,sayInput);
				connectBtn.visible = false;
				clock = setTimeout(MsgTimeout,TIMEOUT);
			});
			myInterface = new UserInterFace(this);
			ConferConfig();
		}
		//初始化
		function initializtion(){
			info = JSON.decode(ldr.list['init']);
			ldr.path = info.path;
			gameScene.road = info.road;
			
			ldr.load('scene',info.scene);
			ldr.load('map',info.map);
			for(var i:int = 0;i < info.icon.length;i++){
				ldr.load(info.icon[i]);
			}
			ldr.load('portrait',info.portrait);
			ldr.callback = enterScene;
		}
		//初始化图片加载
		function enterScene(){
			gameScene.setMap(ldr.list['scene']);
			gameScene.pass = helper.decode(ldr.list['map']);
			myInterface.setIcon(ldr.list[info.icon[0]],0);
			myInterface.setIcon(ldr.list[info.icon[1]],1);
			myInterface.coolBtn.setIcon(ldr.list[info.icon[2]]);
			myInterface.setPortrait(ldr.list['portrait'])
		}
		function showMsg(str:String){
			dialog.appendText(str+'\n')
			dialog.verticalScrollPosition = dialog.maxVerticalScrollPosition;
		}
		function recieve(e){
			protocol();
		}
		//指令接收
		function protocol_start(){
    	    socket.readUTFBytes(socket.bytesAvailable);
			protocol = protocol_run;
		}
		function protocol_run(){
			var statement:Array = decode(readBytes());
			for(var i:int = 0;i < statement.length;i++){
				var notify = erlang.decode(statement[i]);
				for(var j:int = 1;j < notify.length;j++){
					var item = notify[j];
					if(item is String && item.charAt() == '{'){
						try{notify[j] = JSON.decode(item);}catch(e){}
					}
				}
				//trace(notify);
				confer[notify[0]](notify);
			}
		}
		function addPlayer(msg,pic){
			var role = gameScene.addPlayer(msg.name);
			role.setMoves(pic);
			role.globalX = msg.x;role.globalY = msg.y;
			role.turn(msg.x+msg.dx,msg.y+msg.dy);
			role.pass = rolePass;
			return role
		}
		function rolePass(role){
			roadPass(true,role);
		}
		function roadPass(v,role){
			switch(v){
				//没有障碍时行走
				case true:
					role.globalX += role.dx;
					role.globalY += role.dy;
					role.x = role.globalX;
					role.y = role.globalY;
					gameScene.Zaxis(role);
					role.dx = 0;
					role.dy = 0;
					return true;
				//有障碍时行走
				case false:
				default:
					var dx:Number = role.dx
					var dy:Number = role.dy;
					var flag = false;
					if(dx > 1 || dx < -1){
						role.dy = 0;
						flag = gameScene.getRoad(role);
					}
					if((dy > 1 || dy < -1) && (flag === undefined || flag !== true)){
						role.dy = dy;
						role.dx = 0;
						flag = gameScene.getRoad(role);
					
					}
					if(flag !== true){
						role.target.length = 0;
					}else{
						role.globalX += role.dx;
						role.globalY += role.dy;
						role.x = role.globalX;
						role.y = role.globalY;
					}
					return false;
			}
		}
		function readBytes(){
		    var byte:ByteArray = new ByteArray();
			socket.readBytes(byte);
			count++
	        return byte;
		}
		function newLoader(url:String){
			var sldr:SimpleLoader = new SimpleLoader(info.path+url);
			return sldr;
		}
		//指令发送
		function sendMsg(atom:String,...arg){
			var arr:Array = [];
			arr.push(erlang.atom(atom));
			for(var i:int = 0;i < arg.length;i++){
				if(arg[i] is Number){
					arr.push(erlang.integer(int(arg[i])));
				}else if(arg[i] is String){
					arr.push(erlang.string(arg[i]));
				}else{
					arr.push(erlang.string(JSON.encode(arg[i])));
				}
			}
			//trace(atom,arg);
			socket.writeBytes(encode(erlang.head(erlang.tuple(arr))));
			socket.flush();
			//超时判定
			clearTimeout(clock);
			clock = setTimeout(MsgTimeout,TIMEOUT);
		}
		//指令封抱
		function encode(data:ByteArray):ByteArray{
			var byte:ByteArray = new ByteArray();
			byte.writeShort(data.length);
			byte.writeBytes(data);
			byte.writeShort(0xFFFF);
			return byte;
		}
		//指令拆包
		function decode(data:ByteArray){
			buffer.writeBytes(data);
			buffer.position = 0;
			var stack:Array = [],point:int = 0,span:int;
			while(buffer.position+2 <= buffer.length){
				var len:int = buffer.readUnsignedShort();
				if(buffer.position + len + 2 <= buffer.length){
					var tmp:ByteArray = new ByteArray();
					buffer.readBytes(tmp,0,len);
					span = buffer.readUnsignedShort();
					if(span == 0xFFFF){
						stack.push(tmp);
						point = buffer.position;
					}else{
						buffer.position = point;
						while(buffer.position+2 <= buffer.length){
							span = buffer.readUnsignedShort();
							if(span == 0xFFFF){
								point = buffer.position;
								break;
							}
							buffer.position--;
						}
						break;
					}
				}else break;
			}
			buffer.position = point;
			var result = new ByteArray();
			result.readBytes(buffer);
			buffer = result;
			return stack;
		}
		function keySend(e:KeyboardEvent):void{
			switch(e.keyCode){
				case Keyboard.ENTER:
					sayInput()
			}
		}
		function sayInput(e = null){
			if(input.text != ''){
				var msg = {};
				msg.text = escapeMultiByte(input.text);
				msg.name = my.name;
				if(privacyBar.text == ''){
					sendMsg('say',msg);
					showMsg(msg.name+':'+input.text);
				}else{
					sendMsg('privacy',privacyBar.text,msg);
				}
				input.text = ''
			}
		}
		function MsgTimeout(){
			sendMsg('timeout');
		}
		function getPlayerInfo(name,e){
			sendMsg('getinfo',name);
			e.stopPropagation();
		}
		function showPlayerInfo(role,e = null){
			lock = role;
			my.turn(role.x,role.y);
			myInterface.showPlayerInfo(role);
			if(e)e.stopPropagation();
		}
		function conferParse(notify,...seq){
			var result:Array = [];
			for(var i:int = 0;i < seq.length;i++){
				result.push(JSON.decode(notify[seq[i]]));
			}
			return result;
		}
		//魔法施放
		function fireMagic(name,from,to){
			var target = gameScene.getPlayer(to)
			var shooter = gameScene.getPlayer(from)
			if(target == null || shooter == null)return;
			var m:Object = info.magic[name];			
			var sldr = newLoader(m.pic);
			sldr.callback = function(){
				var ani = new animation(sldr.gut,m.col,m.row,m.valid);
				ani.setDuration(gameScene.extraLayer,m.duration);
				ani.end = function(){}
				ani.x = target.globalX;ani.y = target.globalY;
				ani.start();
			}
			
			var sldr2 = newLoader(info.fire.pic);
			sldr2.callback = function(){
				var ani = new animation(sldr2.gut,info.fire.col,info.fire.row,info.fire.valid);
				ani.setDuration(gameScene.extraLayer,info.fire.duration);
				ani.x = shooter.globalX;ani.y = shooter.globalY;
				ani.start();
			}
			target.info.HP -= m.power;
			if(target.info.HP < 0)target.info.HP = 0;
			if(target == lock)showPlayerInfo(target);
			else if(target == my)myInterface.showMyInfo();
		}
		//指令处理
		function ConferConfig(){
			confer['init'] = function (notify){
				var msg = {},sub = {};
				msg.figure = info.figure[int(info.figure.length*Math.random())];
				sub.name = notify[1];
				sub.x = 200;sub.y = 200;sub.dx = 1;sub.dy = 1;
				var sldr = newLoader(msg.figure);
				sldr.callback = function(e){
					my = addPlayer(sub,sldr.gut);
					gameScene.watch(my.globalX,my.globalY);
					my.pass = function(role){
						gameScene.mapPass(role);
						flushCount--;
						if(flushCount <= 0){
							sendMsg('position',role.globalX,role.globalY)
							flushCount = flushRate;
						}
					}
					my.start();
					stage.addEventListener(Event.ENTER_FRAME,function(e){
						gameScene.watch(my.globalX,my.globalY)}
					);
					gameScene.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent){
						var msg = {};
						msg.name = my.name;
						msg.x = gameScene.sightX+e.stageX
						msg.y = gameScene.sightY+e.stageY
						msg.dx = msg.x-my.x;
						msg.dy = msg.y-my.y;
						sendMsg('move',msg);						
						my.addTarget(msg.x,msg.y);
					});
					myInterface.setPortraitName()
					my.info.type = 'player';
					my.info.HP = 100;
					my.info.MaxHP = 100;
					my.info.MP = 100;
					my.info.MaxMP = 100;
					my.info.avatar = msg.figure;
					myInterface.showMyInfo();
				}
				sendMsg('init',msg,sub,info.portrait,sub.x,sub.y);
			}
			confer['add'] = function (notify){
				var msg = notify[2];
				showMsg(msg.name +'进入');
				var sldr = newLoader(notify[1].figure);
				sldr.callback = function(e){
					var role = gameScene.addPlayer(msg.name);
					role.setMoves(sldr.gut);
					role.globalX = notify[3];
					role.globalY = notify[4];
					role.pass = gameScene.mapPass
					role.turn(role.globalX+msg.dx,role.globalY+msg.y);
					role.start();
					role.addTarget(msg.x,msg.y);
					role.useHandCursor = true;
					role.buttonMode = true;
					role.mouseChildren = true;
					role.info.type = 'player';
					role.info.HP = notify[5][0];
					role.info.MaxHP = notify[5][1];
					role.info.MP = notify[5][2];
					role.info.MaxMP = notify[5][3];
					role.info.avatar = notify[5][4]
					role.addEventListener(MouseEvent.MOUSE_DOWN,function(e){showPlayerInfo(role,e)});
				}
			}
			confer['move'] = function (notify){
				var msg = notify[1]
				var role = gameScene.getPlayer(msg.name);
				role.globalX = msg.x-msg.dx;
				role.globalY = msg.y-msg.dy;
				role.addTarget(msg.x,msg.y);
			}
			confer['say'] = function (notify){
				showMsg(notify[1].name + ':' + unescapeMultiByte(notify[1].text));
			}
			confer['del'] = function (notify){
				showMsg(notify[1] +'退出');
				if(gameScene.getPlayer(notify[1]) == lock){
					lock = null;
					myInterface.playerView.visible = false;
				}
				gameScene.delPlayer(notify[1]);
				
			}
			confer['privacy'] = function (notify){
				if(notify[1] == my.name){
					showMsg(notify[2].name + '对你说:'+notify[2].text);
				}else{
					showMsg('你对'+notify[1]+'说:'+notify[2].text);
				}
			}
			confer['get'] = function (notify){
				if(notify[1] == 'overview'){
					var pinfo = notify[3];
					myInterface.showPlayerView(notify[2],pinfo[0],pinfo[1],pinfo[2],pinfo[3],pinfo[4])
					lock = gameScene.getPlayer(notify[2]);
				}
			}
			confer['none'] = function (notify){
				showMsg('找不到玩家'+notify[1]);
			}
			confer['magic'] = function (notify){
				gameScene.getPlayer(notify[2]).clearTarget();
				fireMagic(notify[1],notify[2],notify[3]);
			}
			confer['monster'] = function (notify){
				var m:Object;
				if(notify[1] == 'add'){
					m = notify[2];
					var sldr = newLoader(info.monster[m[0]]);
					
					sldr.callback = function(e){
						var role = gameScene.addPlayer(m[0]);
						role.setMoves(sldr.gut);
						role.globalX = m[1];
						role.globalY = m[2];
						role.pass = rolePass;
						role.turn(int(Math.random()*8));
						role.start();
						role.useHandCursor = true;
						role.buttonMode = true;
						role.mouseChildren = true;
						role.info.type = 'monster'
						role.info.HP = m[3][0];
						role.info.MaxHP = m[3][1];
						role.info.MP = m[3][2];
						role.info.MaxMP = m[3][3];
						role.addEventListener(MouseEvent.MOUSE_DOWN,function(e){showPlayerInfo(role,e)});
					}
				}else if(notify[1] == 'target'){
					m = notify[2];
					var role = gameScene.getPlayer(m[0])
					if(role == null)return;
					role.addTarget(m[1],m[2]);
				}else if(notify[1] == 'kill'){
					gameScene.delPlayer(notify[2]);
					myInterface.closePlayerInfo();
				}
			}
		}
	}
}

